package com.linghang.wusthelper.service.Impl;

import com.auth0.jwt.JWT;
import com.github.pagehelper.PageHelper;
import com.linghang.wusthelper.common.ServerResponse;
import com.linghang.wusthelper.common.URLConst;
import com.linghang.wusthelper.dao.primary.BookRentHistoryDao;
import com.linghang.wusthelper.dao.primary.LibAnnouncementDao;
import com.linghang.wusthelper.dao.primary.StudentDao;
import com.linghang.wusthelper.entity.primary.*;
import com.linghang.wusthelper.redis.RedisService;
import com.linghang.wusthelper.service.LibraryService;
import com.linghang.wusthelper.spider.library.*;
import com.linghang.wusthelper.util.EncryptUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import us.codecraft.webmagic.Spider;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author origin
 * 图书馆service实现类
 */
@Service("LibraryService")
public class LibraryServiceImpl implements LibraryService {


    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private BookRentHistoryDao bookRentHistoryDao;

    @Autowired
    private StudentDao studentDao;

    @Autowired
    private LibAnnouncementDao libAnnouncementDao;

    @Autowired
    private RedisService redisService;

    /**
     * 图书馆登陆
     * @param token
     * @param password
     * @return
     */
    @Override
    public ServerResponse login(String token, String password) {
        String stuNum = JWT.decode(token).getClaim("stuNum").asString();
        redisService.remove(stuNum+":PHPSESSID");
        Map<String,String> resultMap = LibSimLogin.login(stuNum,password);
        if (resultMap.get("code").equals("0")){
            return ServerResponse.createByLIBError();
        }else if (resultMap.get("code").equals("2")){
            return ServerResponse.createByErrorMsg(resultMap.get("errorMsg"));
        }else {
            Student student = studentDao.selectByStuNum(stuNum);
            //  首次登陆或者图书馆密码已更改
            //  并非首次登陆且密码未更改则无需update，减少数据库请求
            if (student.getLibPassword() == null || student.getLibPassword().equals("") || !student.getLibPassword().equals(EncryptUtil.encryptPasswd(password))){
                studentDao.updateLIBPassword(stuNum,EncryptUtil.encryptPasswd(password));
            }
            return ServerResponse.createBySuccessMsg("登陆成功");
        }
    }

    /**
     * 获取当前借阅记录
     * @param token
     * @return
     * @throws InterruptedException
     */
    @Override
    public ServerResponse getRentInfo(String token) throws InterruptedException {
        String stuNum = JWT.decode(token).getClaim("stuNum").asString();
        Student student = studentDao.selectByStuNum(stuNum);
        Map<String,String> resultMap = LibSimLogin.login(stuNum,EncryptUtil.decryptPasswd(student.getLibPassword()));
        if (resultMap.get("code").equals("0")){
            //  图书馆未能访问,不返回数据
            return ServerResponse.createByLIBError();
        }else if (resultMap.get("code").equals("2")){
            return ServerResponse.createByErrorMsg("图书馆密码已更改，请重新登录");
        }else {
            String lock = new String("");
            List<BookRent> bookRentList = new ArrayList<>();
            Spider.create(new LibBookRentSpider(resultMap.get("PHPSESSID"),bookRentList,lock))
                    .addUrl(URLConst.LIBBOOKRENTURL)
                    .thread(1)
                    .runAsync();
            synchronized (lock){
                lock.wait();
            }
            return ServerResponse.createBySuccess("获取当前借阅记录成功",bookRentList);
        }
    }

    /**
     * 获取借阅历史
     * @param token
     * @return
     * @throws InterruptedException
     */
    @Override
    public ServerResponse getRentHistory(String token) throws InterruptedException {
        String stuNum = JWT.decode(token).getClaim("stuNum").asString();
        Student student = studentDao.selectByStuNum(stuNum);
        String pas = student.getLibPassword();
        Map<String,String> resultMap = LibSimLogin.login(stuNum,EncryptUtil.decryptPasswd(student.getLibPassword()));
        if (resultMap.get("code").equals("0")){
            //  图书馆未能访问，返回本地数据
            List<BookRentHistory> bookRentHistoryList = bookRentHistoryDao.selectListByStuNum(stuNum);
            return ServerResponse.createByLIBError(bookRentHistoryList);
        }else if (resultMap.get("code").equals("2")){
            return ServerResponse.createByErrorMsg("图书馆密码已更改，请重新登录");
        }else{
            String lock = new String("");
            Spider.create(new LibRentHistorySpider(resultMap.get("PHPSESSID"),stuNum,bookRentHistoryDao,lock))
                    .addUrl(URLConst.LIBRENTHISTORYURL)
                    .thread(1)
                    .runAsync();
            synchronized (lock){
                lock.wait();
            }
            List<BookRentHistory> bookRentHistoryList = bookRentHistoryDao.selectListByStuNum(stuNum);
            return ServerResponse.createBySuccess("获取借阅历史成功",bookRentHistoryList);
        }
    }

    /**
     * 获取图书信息
     * @param bookUrl
     * @return
     * @throws InterruptedException
     */
    @Override
    public ServerResponse getBookInfo(String bookUrl) throws InterruptedException {
        BookInfo bookInfo = new BookInfo();
        String lock = new String("");
        Spider.create(new LibBookInfoSpider(bookInfo,lock))
                .addUrl(bookUrl)
                .thread(1)
                .runAsync();
        synchronized (lock){
            lock.wait();
        }
        log.info("2");
        if (bookInfo.getBookNameAndAuth() != null){
            return ServerResponse.createBySuccess("获取图书信息成功",bookInfo);
        }else {
            return ServerResponse.createByLIBError();
        }
    }

    /**
     * 获取图书馆公告
     * @return
     * @throws InterruptedException
     */
    @Override
    public ServerResponse getAnnouncementList(int pageNum,int pageSize){
        PageHelper.startPage(pageNum,pageSize);
        List<LibAnnouncement> libAnnouncementList = libAnnouncementDao.selectList();
        return ServerResponse.createBySuccess("获取公告成功",libAnnouncementList);
    }

    /**
     * 获取公告内容
     * @param announcementId
     * @return
     */
    @Override
    public ServerResponse getAnnouncementContent(int announcementId) {
        String content = libAnnouncementDao.getContent(announcementId);
        return ServerResponse.createBySuccess("获取公告内容成功",content);
    }
}
